<%+cbi/valueheader%>
<%
local cbid = "cbid." .. self.config .. "." .. section .. "." .. self.option

-- 读取 MultiValue
local values = {}
for i, key in pairs(self.keylist) do
	values[#values + 1] = {
		key = key,
		label = self.vallist[i] or key,
		group = self.group and self.group[i] or nil
	}
end

-- 获取选中值
local selected = {}
local cval = self:cfgvalue(section)
if type(cval) == "table" then
	for _, v in pairs(cval) do
		selected[v] = true
	end
elseif type(cval) == "string" then
	for v in cval:gmatch("%S+") do
		selected[v] = true
	end
end

-- 按原顺序分组
local groups = {}
local group_order = {}
for _, item in ipairs(values) do
	local g = item.group
	if not g or g == "" then 
		g = translate("default") 
	end
	if not groups[g] then 
		groups[g] = {}
		table.insert(group_order, g)
	end
	table.insert(groups[g], item)
end
%>

<style>
/* 组标题的右箭头（折叠） */
.lv-arrow-right {
	width: 0;
	height: 0;
	border-top: 4px solid transparent;
	border-bottom: 4px solid transparent;
	border-left: 5px solid #555;
	display: inline-block;
	vertical-align: middle;
}

/* 组标题的下箭头（展开） */
.lv-arrow-down-small {
	width: 0;
	height: 0;
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	border-top: 5px solid #555;
	display: inline-block;
	vertical-align: middle;
}
</style>

<div id="<%=cbid%>" class="cbi-input-select" style="display: inline-block;">
	<!-- 搜索 -->
	<input type="text"
		id="<%=cbid%>.search"
		class="node-search-input cbi-input-text"
		placeholder="<%:Search nodes...%>"
		oninput="filterGroups_<%=self.option%>(this.value)"
		style="width:100%;padding:6px;margin-bottom:8px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;max-height:36px;" />
	<!-- 主容器 -->
	<div style="max-height:300px; overflow:auto; margin-bottom:8px; white-space:nowrap;">
		<ul class="cbi-multi" id="<%=cbid%>.node_list" style="padding:0 !important;margin:0 !important;width:100%;box-sizing:border-box;">
			<% for _, gname in ipairs(group_order) do %>
			<% 	local items = groups[gname] %>
			<li class="group-block" data-group="<%=gname%>" style="list-style:none; padding:0; margin:0 0 8px 0;">
				<!-- 组标题 -->
				<div class="group-title"
					onclick="toggleGroup_<%=self.option%>('<%=gname%>')"
					style="cursor:pointer;padding:6px;background:#f0f0f0;border-radius:4px;margin-bottom:4px;display:flex;align-items:center;white-space:nowrap;">
					<span id="arrow-<%=self.option%>-<%=gname%>" class="lv-arrow-down-small"></span>
					<b style="margin-left:8px;"><%=gname%></b>
					<span id="group-count-<%=self.option%>-<%=gname%>" style="margin-left:8px;color:#007bff;">
						(0/<%=#items%>)
					</span>
				</div>
				<!-- 组内容（可折叠）-->
				<ul id="group-<%=self.option%>-<%=gname%>" style="margin:0 0 8px 16px; padding:0; list-style:none;">

				<% for _, item in ipairs(items) do %>
					<li data-node-name="<%=pcdata(item.label):lower()%>" style="list-style:none;padding:0;margin:0;white-space:nowrap;" title="<%=pcdata(item.label)%>">
						<input
							type="checkbox"
							class="cbi-input-checkbox"
							style="vertical-align: middle; margin-right:6px;"
							<%= attr("id",   cbid .. "." .. item.key) ..
								attr("name", cbid) ..
								attr("value", item.key) ..
								ifattr(selected[item.key], "checked", "checked")
							%> />
						<label for="<%=cbid .. "." .. item.key%>"><%=pcdata(item.label)%></label>
					</li>
				<% end %>
				</ul>
			</li>
			<% end %>
		</ul>
	</div>
	<!-- 控制栏 -->
	<div style="margin-top:4px;display:flex;gap:4px;align-items:center;">
		<input class="btn cbi-button cbi-button-edit" type="button" onclick="selectAll_<%=self.option%>(true)" value="<%:Select all%>">
		<input class="btn cbi-button cbi-button-edit" type="button" onclick="selectAll_<%=self.option%>(false)" value="<%:DeSelect all%>">
		<span id="count-<%=self.option%>" style="color:#666;"></span>
	</div>
</div>
<%+cbi/valuefooter%>

<script type="text/javascript">
//<![CDATA[
(function(){
	const cbid = "<%=cbid%>";
	const opt = "<%=self.option%>";
	const listId = cbid + ".node_list";

	// 折叠组
	window["toggleGroup_" + opt] = function(g){
		const ul = document.getElementById("group-" + opt + "-" + g);
		const arrow = document.getElementById("arrow-" + opt + "-" + g);
		if (!ul) return;
		// 判断是否在搜索状态
		const keyword = document.getElementById(cbid + ".search").value.trim().toLowerCase();
		const isSearching = keyword.length > 0;
		// 搜索状态下，仅切换当前组，不处理其他组
		if (isSearching) {
			if (ul.style.display === "none") {
				ul.style.display = "";
				if (arrow) arrow.className = "lv-arrow-down-small";
			} else {
				ul.style.display = "none";
				if (arrow) arrow.className = "lv-arrow-right";
			}
			return;
		}
		// 非搜索模式：先折叠其他组
		const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
		groups.forEach(group=>{
			const gname = group.getAttribute("data-group");
			const gul = document.getElementById("group-" + opt + "-" + gname);
			const garrow = document.getElementById("arrow-" + opt + "-" + gname);
			if (gname !== g) {
				if (gul) gul.style.display = "none";
				if (garrow) arrow.className = "lv-arrow-right";
			}
		});
		document.getElementById(listId).parentNode.scrollTop = 0;
		// 切换当前组
		if (ul.style.display === "none") {
			ul.style.display = "";
			if (arrow) arrow.className = "lv-arrow-down-small";
		} else {
			ul.style.display = "none";
			if (arrow) arrow.className = "lv-arrow-right";
		}
	};

	// 搜索
	window["filterGroups_" + opt] = function(keyword){
		keyword = keyword.toLowerCase().trim();

		const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");

		groups.forEach(group=>{
			const items = group.querySelectorAll("li[data-node-name]");
			let matchCount = 0;

			items.forEach(li=>{
				const name = li.getAttribute("data-node-name");
				if (!keyword || name.indexOf(keyword) !== -1) {
					li.style.display = "";
					matchCount++;
				} else {
					li.style.display = "none";
				}
			});
			// 搜索时自动展开所有组
			const gname = group.getAttribute("data-group");
			const ul = document.getElementById("group-" + opt + "-" + gname);
			const arrow = document.getElementById("arrow-" + opt + "-" + gname);

			if (matchCount === 0 && keyword !== "") {
				group.style.display = "none";
			} else {
				group.style.display = "";
				if (keyword) {
					ul.style.display = "";
					arrow.className = "lv-arrow-down-small";
				}
			}
		});

		updateCount();

		// 清空搜索后恢复全部折叠
		if (!keyword) {
			const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
			groups.forEach(group=>{
				const gname = group.getAttribute("data-group");
				const ul = document.getElementById("group-" + opt + "-" + gname);
				const arrow = document.getElementById("arrow-" + opt + "-" + gname);
				if (ul) ul.style.display = "none";
				if (arrow) arrow.className = "lv-arrow-right";
			});
		}
	};

	// 全选 / 全不选
	window["selectAll_" + opt] = function(flag){
		const cbs = document.querySelectorAll("[id='" + listId + "'] input[type=checkbox]");
		cbs.forEach(cb=>{
			if (cb.offsetParent !== null) cb.checked = flag;
		});
		updateCount();
	};

	// 计数
	function updateCount(){
		const cbs = document.querySelectorAll("[id='" + listId + "'] input[type=checkbox]");
		let checked = 0;
		cbs.forEach(cb=>{ if (cb.checked) checked++; });
		// 更新总计
		document.getElementById("count-" + opt).innerHTML =
			"<%:Selected:%> <span style='color:red;'>" + checked + " / " + cbs.length + "</span>";
		
		// 更新每个组
		const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
		groups.forEach(group=>{
			const gname = group.getAttribute("data-group");
			const groupCbs = group.querySelectorAll("li[data-node-name] input[type=checkbox]");
			let groupChecked = 0;
			groupCbs.forEach(cb=>{ if(cb.checked) groupChecked++; });
			const span = document.getElementById("group-count-" + opt + "-" + gname);
			if(span) span.textContent = "(" + groupChecked + "/" + groupCbs.length + ")";
		});
	}

	document.getElementById(listId)?.addEventListener("change", updateCount);

	// 初始化折叠所有组和计数
	const initObserver = new MutationObserver(() => {
		const list = document.getElementById(listId);
		if (!list) return;

		if (list.offsetParent === null) return;

		if (list.dataset.initDone === "1") return;
		list.dataset.initDone = "1";

		const groups = document.querySelectorAll("[id='" + listId + "'] .group-block");
		groups.forEach(group => {
			const gname = group.getAttribute("data-group");
			const ul = document.getElementById("group-" + opt + "-" + gname);
			const arrow = document.getElementById("arrow-" + opt + "-" + gname);
			if (ul) ul.style.display = "none";
			if (arrow) arrow.className = "lv-arrow-right";
		});

		updateCount();
	});

	initObserver.observe(document.body, {
		attributes: true,
		subtree: true,
		attributeFilter: ["style", "class"]
	});

})();
//]]>
</script>
